// 坡度测量
import BaseMeasure from "./baseMeasure";
import "../prompt/prompt.css";
import Prompt from "../prompt/prompt.js";

/**
 * 坡度测量类
 * @class
 * @augments BaseMeasure
 * @alias BaseMeasure.MeasureSlope
 */
class MeasureSlope extends BaseMeasure {
  constructor(viewer, opt) {
    super(viewer, opt);
    this.type = "mesureSlop";
    this.style = opt.style || {};
    this.viewer = viewer;
    this.label = undefined;
    this.point = undefined;
    this.arrow = undefined;
  }

  // 开始测量
  start(callabck) {
    this.state = "startCreate";
    let that = this;
    if (!this.prompt && this.promptStyle.show)
      this.prompt = new Prompt(this.viewer, this.promptStyle);
    this.handler.setInputAction(function (evt) {
      //单击开始绘制
      let cartesian = that.getCatesian3FromPX(evt.position, that.viewer);
      if (!cartesian) return;
      if (!that.point) that.point = that.createPoint(cartesian);
      that.point.position.setValue(cartesian);
      that.getSlope(cartesian, function (direction, slop, angle) {
        if (!that.label) that.label = that.createLabel(cartesian, "");
        that.label.position.setValue(cartesian);
        const slopVal = (slop * 100).toFixed(2) + "%";
        that.label.label.text =
          "坡度：" + angle.toFixed(2) + "°" + "(" + slopVal + ")";
        // 创建坡向箭头
        if (!that.arrow) {
          that.arrow = that.createArrow(cartesian, direction);
        }
      });
      if (callabck) callabck();
      that.endCreate();
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.handler.setInputAction(function (evt) {
      that.state = "creating";
      if (that.prompt) that.prompt.update(evt.endPosition, "点击开始测量");
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }

  endCreate() {
    let that = this;
    if (that.handler) {
      that.handler.destroy();
      that.handler = undefined;
    }
    if (that.prompt) {
      that.prompt.destroy();
      that.prompt = undefined;
    }
    that.state = "endCreate";
  }

  startEdit(callback) {
    if (!((this.state == "endCreate" || this.state == "endEdit") && this.point))
      return;
    this.state = "startEdit";
    if (!this.modifyHandler)
      this.modifyHandler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
    this.modifyHandler.setInputAction(function (evt) {
      let pick = that.viewer.scene.pick(evt.position);
      if (Cesium.defined(pick) && pick.id && pick.id.wz != undefined) {
        if (!pick.id.objId) that.modifyPoint = pick.id;
        that.forbidDrawWorld(true);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    this.modifyHandler.setInputAction(function (evt) {
      if (that.positions.length < 1 || !that.modifyPoint) return;
      let cartesian = that.getCatesian3FromPX(evt.endPosition, that.viewer);
      if (!cartesian) return;
      that.modifyPoint.position.setValue(cartesian.clone());

      that.positions[that.modifyPoint.wz] = cartesian.clone();
      let heightAndCenter = that.getHeightAndCenter(
        that.positions[0],
        that.positions[1]
      );
      let text = that.formateLength(heightAndCenter.height, that.unit);
      that.floatLabel.label.text = "高度差：" + text;
      that.floatLabel.length = heightAndCenter.height;
      if (heightAndCenter.center)
        that.floatLabel.position.setValue(heightAndCenter.center);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    this.modifyHandler.setInputAction(function (evt) {
      if (!that.modifyPoint) return;
      that.modifyPoint = undefined;
      that.lastPosition = undefined;
      that.nextPosition = undefined;
      that.forbidDrawWorld(false);
      if (callback) callback();
      that.state = "endEdit";
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
  }

  endEdit() {
    if (this.modifyHandler) {
      this.modifyHandler.destroy();
      this.modifyHandler = undefined;
    }
    that.forbidDrawWorld(false);
    this.state = "endEdit";
  }

  done() {
    if (this.state == "startCreate") {
      this.destroy();
    } else if (this.state == "startEdit" || this.state == "editing") {
      this.endEdit();
    } else {
      this.endCreate();
    }
  }

  // 清除测量结果
  destroy() {
    this.state = "no";
    if (this.label) {
      this.viewer.entities.remove(this.label);
      this.label = undefined;
    }
    if (this.point) {
      this.viewer.entities.remove(this.point);
      this.point = undefined;
    }
    if (this.arrow) {
      this.viewer.entities.remove(this.arrow);
      this.arrow = undefined;
    }

    if (this.handler) {
      this.handler.destroy();
      this.handler = undefined;
    }
  }

  createPoint(position) {
    return this.viewer.entities.add({
      position: position,
      point: {
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        show: true,
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.RED,
        outlineWidth: 2,
        pixelSize: 6,
        outlineWidth: 3,
        disableDepthTestDistance: Number.MAX_VALUE,
      },
    });
  }

  createArrow(center, direction) {
    let p = Cesium.Cartesian3.multiplyByScalar(
      direction,
      10,
      new Cesium.Cartesian3()
    );
    p = Cesium.Cartesian3.add(center, p, new Cesium.Cartesian3());
    const arrow = this.viewer.entities.add({
      name: "Purple straight arrow at height",
      polyline: {
        positions: [center, p.clone()],
        width: 3,
        material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.YELLOW),
        clampToGround: true,
      },
    });
    return arrow;
  }
}

export default MeasureSlope;
